Skip to content

feat(transport): add which_command for cross-platform executable resolution#774

Open
kakarot-dev wants to merge 1 commit intomodelcontextprotocol:mainfrom
kakarot-dev:feat/which-command
Open

feat(transport): add which_command for cross-platform executable resolution#774
kakarot-dev wants to merge 1 commit intomodelcontextprotocol:mainfrom
kakarot-dev:feat/which-command

Conversation

@kakarot-dev
Copy link
Copy Markdown
Contributor

Summary

Adds a which_command() helper function that resolves executable paths via the which crate before constructing a tokio::process::Command. This fixes Windows failures where .cmd shim scripts (e.g. npx.cmd) are not found by Command::new() without a fully-qualified path.

Changes:

  • Added which_command(name) -> io::Result<Command> to child_process.rs
  • Added which v7 as an optional dependency, gated behind transport-child-process feature
  • Re-exported which_command from transport module
  • Added tests for known binary resolution and nonexistent binary error handling

Usage:

use rmcp::transport::{which_command, ConfigureCommandExt};

let cmd = which_command("npx")?
    .configure(|cmd| {
        cmd.arg("-y").arg("@modelcontextprotocol/server-everything");
    });

Closes #456

…lution

Adds a `which_command()` helper that resolves executable paths via the
`which` crate before constructing a `tokio::process::Command`. This fixes
Windows failures where `.cmd` shim scripts (e.g. `npx.cmd`) are not
found by `Command::new()` without a fully-qualified path.

Closes modelcontextprotocol#456
@kakarot-dev kakarot-dev requested a review from a team as a code owner March 25, 2026 15:37
@github-actions github-actions bot added T-dependencies Dependencies related changes T-config Configuration file changes T-core Core library changes T-transport Transport layer changes labels Mar 25, 2026
"transport-async-rw",
"tokio/process",
"dep:process-wrap",
"dep:which",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The which crate is now included for everyone using transport-child-process, even on Linux and macOS where Command::new already resolves PATH correctly. Since this is a library crate, it might be a good idea to make it a separate feature flag so users can opt in explicitly.

which-command = [
  "transport-child-process",
  "dep:which",
]

///
/// # Example
/// ```rust,no_run
/// use rmcp::transport::child_process::{which_command, ConfigureCommandExt};
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are re-exported.

Suggested change
/// use rmcp::transport::child_process::{which_command, ConfigureCommandExt};
/// use rmcp::transport::{which_command, ConfigureCommandExt};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-config Configuration file changes T-core Core library changes T-dependencies Dependencies related changes T-transport Transport layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The abstract method uses which under the hood.

2 participants